package com.hanqian.kepler.web.controller.core;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import com.hanqian.kepler.common.bean.NameValueVo;
import com.hanqian.kepler.common.bean.jqgrid.JqGridContent;
import com.hanqian.kepler.common.bean.jqgrid.JqGridFilter;
import com.hanqian.kepler.common.bean.jqgrid.JqGridPager;
import com.hanqian.kepler.common.bean.jqgrid.JqGridReturn;
import com.hanqian.kepler.common.bean.result.AjaxResult;
import com.hanqian.kepler.common.enums.DictEnum;
import com.hanqian.kepler.common.jpa.specification.Rule;
import com.hanqian.kepler.core.entity.primary.core.TargetDesc;
import com.hanqian.kepler.core.entity.primary.core.TargetDescHistory;
import com.hanqian.kepler.core.service.core.TargetDescHistoryService;
import com.hanqian.kepler.core.service.core.TargetDescService;
import com.hanqian.kepler.core.service.core.TargetDescZanService;
import com.hanqian.kepler.core.service.core.TargetService;
import com.hanqian.kepler.flow.entity.User;
import com.hanqian.kepler.flow.enums.FlowEnum;
import com.hanqian.kepler.flow.vo.ProcessLogVo;
import com.hanqian.kepler.security.annotation.CurrentUser;
import com.hanqian.kepler.web.annotation.RequestJsonParam;
import com.hanqian.kepler.web.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * 指标描述
 * ============================================================================
 * author : dzw
 * createDate:  2020/12/24 。
 * ============================================================================
 */
@Controller
@RequestMapping("targetDesc")
public class TargetDescController extends BaseController {

	@Autowired
	private TargetService targetService;
	@Autowired
	private TargetDescService targetDescService;
	@Autowired
	private TargetDescHistoryService targetDescHistoryService;
	@Autowired
	private TargetDescZanService targetDescZanService;

	/**
	 * 第一层 - 指标定义分组
	 */
	@GetMapping("list_targetDescDict")
	@ResponseBody
	public JqGridReturn list_targetDescDict(String targetId){
		List<Map<String, Object>> dataRows = new ArrayList<>();
		List<NameValueVo> nameValueVos = targetDescService.findTargetDescDictList(targetId);
		nameValueVos.forEach(vo -> {
			Map<String, Object> map = new HashMap<>();
			map.put("id", StrUtil.emptyIfNull(vo.getValue()));
			map.put("name", StrUtil.emptyIfNull(vo.getName()));
			dataRows.add(map);
		});
		return getJqGridReturn(dataRows, null);
	}

	/**
	 * list - 第二层
	 */
	@GetMapping("list")
	@ResponseBody
	public JqGridReturn list(@CurrentUser User user, JqGridPager pager, @RequestJsonParam("filters") JqGridFilter filters, String targetId, String targetDescDictId){
		Pageable pageable = getJqGridPageable(pager);
		List<Rule> rules = getJqGridSearchWithFlow(filters);
		if(StrUtil.isNotBlank(targetId)){
			rules.add(Rule.eq("target.id", targetId));
		}
		if(StrUtil.isNotBlank(targetDescDictId)){
			rules.add(Rule.eq("targetDescDict.id", targetDescDictId));
		}

		JqGridContent<TargetDesc> jqGridContent = targetDescService.getJqGridContentWithFlow(rules, pageable, user);

		List<Map<String, Object>> dataRows = new ArrayList<>();
		jqGridContent.getList().forEach(entity -> {
			Map<String, Object> map = new HashMap<>();
			map.put("id", entity.getId());
			map.put("content", HtmlUtil.cleanHtmlTag(StrUtil.emptyIfNull(entity.getContent())));
			map.put("zanCount", entity.getZanCount()!=null ? entity.getZanCount() : 0);
			map.put("lastUpdateTime", DateUtil.format(entity.getLastUpdateTime(), "yyyy-MM-dd HH:mm"));
			map.put("version", StrUtil.emptyIfNull(entity.getVersion()));

			dataRows.add(map);
		});
		return getJqGridReturn(dataRows, jqGridContent.getPage());
	}

	/**
	 * read页面
	 */
	@GetMapping("read")
	public String read(String keyId, Model model, String parentId){
		TargetDesc targetDesc = targetDescService.get(keyId);
		model.addAttribute("targetDesc", targetDesc);
		model.addAttribute("target", targetService.get(parentId));

		model.addAttribute("targetDescDictList", getDictList(DictEnum.target_desc)); //指标卡片
		return "main/core/targetDesc_read";
	}

	/**
	 * input页面
	 */
	@GetMapping("input")
	public String input(String keyId, Model model, String parentId, String editType){
		TargetDesc targetDesc = targetDescService.get(keyId);
		model.addAttribute("targetDesc", targetDesc);
		model.addAttribute("target", targetService.get(parentId));
		model.addAttribute("editType", editType);

		model.addAttribute("targetDescDictList", getDictList(DictEnum.target_desc)); //指标卡片
		return "main/core/targetDesc_input";
	}

	/**
	 * 赋值
	 */
	private TargetDesc setData(User user, String keyId, String parentId, String targetDescDictId, String content, String explanation, String ifYuan, String yuan){
		TargetDesc targetDesc = targetDescService.get(keyId);
		if(targetDesc == null){
			targetDesc = new TargetDesc();
			targetDesc.setCreator(user);
		}
		targetDesc.setTarget(targetService.get(parentId));
		targetDesc.setTargetDescDict(dictService.get(targetDescDictId));
		targetDesc.setContent(content);
		targetDesc.setExplanation(explanation);
		targetDesc.setIfYuan(ifYuan);
		targetDesc.setYuan(yuan);

		return targetDesc;
	}

	/**
	 * 保存（系统级别的更新，不会创建历史版本）
	 */
	@PostMapping("save")
	@ResponseBody
	public AjaxResult save(@CurrentUser User user, ProcessLogVo processLogVo, String parentId, String targetDescDictId, String content, String explanation, String ifYuan, String yuan){

		TargetDesc targetDesc = setData(user,processLogVo.getKeyId(),parentId,targetDescDictId,content,explanation,ifYuan,yuan);

		if(StrUtil.isBlank(targetDesc.getId())){
			return targetDescService.draft(targetDesc);
		}else{
			targetDescService.save(targetDesc);
			return AjaxResult.success("保存成功");
		}
	}

	/**
	 * 保存（业务更新，会叠加版本号并创建历史版本）
	 */
	@PostMapping("save_v")
	@ResponseBody
	public AjaxResult save_v(@CurrentUser User user, String keyId, String content, String explanation, String ifYuan, String yuan){
		TargetDesc targetDesc = targetDescService.get(keyId);
		if(targetDesc == null){
			return AjaxResult.error("未获取到原指标描述");
		}
		if(FlowEnum.ProcessState.Draft == targetDesc.getProcessState() || targetDesc.getVersionIndex() == null){
			return AjaxResult.error("数据异常");
		}

		//创建历史版本记录
		AjaxResult ajaxResult = targetDescHistoryService.saveHistoryVersion(targetDesc);
		if(ajaxResult.getState() == 1){
			targetDesc.setContent(content);
			targetDesc.setExplanation(explanation);
			targetDesc.setIfYuan(ifYuan);
			targetDesc.setYuan(yuan);

			targetDesc.setZanCount(0);
			targetDesc.setLastUpdateTime(new Date());
			targetDesc.setVersionIndex(targetDesc.getVersionIndex()+1);
			targetDesc.setVersion("v" + targetDesc.getVersionIndex());
			targetDescService.save(targetDesc);
		}
		return ajaxResult;
	}

	/**
	 * 提交
	 */
	@PostMapping("commit")
	@ResponseBody
	public AjaxResult commit(@CurrentUser User user, ProcessLogVo processLogVo, String parentId, String targetDescDictId, String content, String explanation, String ifYuan, String yuan){

		TargetDesc targetDesc = setData(user,processLogVo.getKeyId(),parentId,targetDescDictId,content,explanation,ifYuan,yuan);
		targetDesc.setCreateTime(new Date());
		if(targetDesc.getVersionIndex() == null){
			targetDesc.setVersionIndex(1);
			targetDesc.setVersion("v1");
			targetDesc.setZanCount(0);
		}

		if(targetDesc.getTarget() == null){
			return AjaxResult.error("未获取到指标卡片信息");
		}

		return targetDescService.commit(targetDesc, processLogVo);
	}

	/**
	 * 审批
	 */
	@PostMapping("approve")
	@ResponseBody
	public AjaxResult approve(@CurrentUser User user, ProcessLogVo processLogVo){
		TargetDesc targetDesc = targetDescService.get(processLogVo.getKeyId());
		return targetDescService.approve(targetDesc, processLogVo);
	}

	/**
	 * 退回
	 */
	@PostMapping("back")
	@ResponseBody
	public AjaxResult back(@CurrentUser User user, ProcessLogVo processLogVo){
		TargetDesc targetDesc = targetDescService.get(processLogVo.getKeyId());
		return targetDescService.back(targetDesc, processLogVo);
	}

	/**
	 * 否决
	 */
	@PostMapping("deny")
	@ResponseBody
	public AjaxResult deny(@CurrentUser User user, ProcessLogVo processLogVo){
		TargetDesc targetDesc = targetDescService.get(processLogVo.getKeyId());
		return targetDescService.deny(targetDesc, processLogVo);
	}

	/**
	 * 撤回
	 */
	@PostMapping("withdraw")
	@ResponseBody
	public AjaxResult withdraw(@CurrentUser User user, ProcessLogVo processLogVo){
		TargetDesc targetDesc = targetDescService.get(processLogVo.getKeyId());
		return targetDescService.withdraw(targetDesc, processLogVo);
	}

	/**
	 * 历史版本列表
	 */
	@GetMapping("list_targetDescHistory")
	@ResponseBody
	public JqGridReturn list_targetDescHistory(@CurrentUser User user, JqGridPager pager, @RequestJsonParam("filters") JqGridFilter filters, String targetDescId){
		Pageable pageable = getJqGridPageable(pager);
		List<Rule> rules = getJqGridSearch(filters);
		if(StrUtil.isNotBlank(targetDescId)) rules.add(Rule.eq("targetDescId", targetDescId));
		JqGridContent<TargetDescHistory> jqGridContent = targetDescHistoryService.getJqGridContent(rules, pageable);

		List<Map<String, Object>> dataRows = new ArrayList<>();
		jqGridContent.getList().forEach(entity -> {
			Map<String, Object> map = new HashMap<>();
			map.put("id", entity.getId());
			map.put("content", StrUtil.emptyIfNull(entity.getContent()));
			map.put("zan", StrUtil.emptyIfNull(entity.getZan()));
			map.put("version", StrUtil.emptyIfNull(entity.getVersion()));
			dataRows.add(map);
		});

		return getJqGridReturn(dataRows, jqGridContent.getPage());
	}

	/**
	 * 历史版本 read页面
	 */
	@GetMapping("read_targetDescHistory")
	public String read_targetDescHistory(String keyId, Model model){
		model.addAttribute("targetDescHistory", targetDescHistoryService.get(keyId));
		return "main/core/targetDescHistory_read";
	}

	/**
	 * 执行点赞
	 */
	@RequestMapping("zan/{id}")
	@ResponseBody
	public AjaxResult zan(@CurrentUser User user, @PathVariable String id){
		if(user == null){
			return AjaxResult.error("未获取到当前登录用户信息");
		}
		TargetDesc targetDesc = targetDescService.get(id);
		if(targetDesc == null){
			return AjaxResult.error("未获取到对应指标描述信息");
		}

		if(targetDescZanService.checkIfZaned(targetDesc, user.getId())){
			return AjaxResult.error("您已经点过赞了");
		}

		return targetDescZanService.zan(targetDesc, user);
	}

}
